/*
 * Copyright (C) 2013 UCWeb Inc. All rights reserved
 * 本代码版权归UC优视科技所有。
 * UC游戏交易平台为优视科技（UC）旗下的手机游戏交易平台产品
 *
 *
 */

package com.dalimao.corelibrary;

import com.dalimao.corelibrary.utils.AttrUtils;
import com.dalimao.corelibrary.utils.LogUtil;
import ohos.agp.components.*;
import ohos.agp.components.element.Element;
import ohos.agp.utils.Color;
import ohos.agp.utils.LayoutAlignment;
import ohos.app.Context;
import ohos.multimodalinput.event.KeyEvent;

import static ohos.agp.components.InputAttribute.*;
import static ohos.agp.utils.TextAlignment.CENTER;

public class VerificationCodeInput extends ComponentContainer implements Component.EstimateSizeListener,
        ComponentContainer.ArrangeListener, Text.TextObserver, Component.FocusChangedListener {

    private final static String TYPE_NUMBER = "number";
    private final static String TYPE_TEXT = "text";
    private final static String TYPE_PASSWORD = "password";
    private final static String TYPE_PHONE = "phone";

    private static final String TAG = "VerificationCodeInput";
    private int box = 4;
    private int boxWidth = 120;
    private int boxHeight = 120;
    private int childHPadding = 14;
    private int childVPadding = 14;
    private String inputType = TYPE_TEXT;
    private Element boxBgFocus = null;
    private Element boxBgNormal = null;
    private Listener listener;
    private TextField currentText;

    public VerificationCodeInput(Context context, AttrSet attrs) {
        super(context, attrs);
        box = AttrUtils.getIntFromAttr(attrs, "box", 4);
        childHPadding = AttrUtils.getDimensionFromAttr(attrs, "child_h_padding", 0);
        childVPadding = AttrUtils.getDimensionFromAttr(attrs, "child_v_padding", 0);
        boxBgFocus = AttrUtils.getElementFromAttr(attrs, "box_bg_focus", boxBgFocus);
        boxBgNormal = AttrUtils.getElementFromAttr(attrs, "box_bg_normal", boxBgNormal);
        inputType = AttrUtils.getStringFromAttr(attrs, "inputType", inputType);
        boxWidth = AttrUtils.getDimensionFromAttr(attrs, "child_width", boxWidth);
        boxHeight = AttrUtils.getDimensionFromAttr(attrs, "child_height", boxHeight);
        initViews();
        setEstimateSizeListener(this);
        setArrangeListener(this);
    }

    /**
     * setBox: 设置输入框个数
     */
    public void setBox(int boxNum) {
        box = boxNum;
        initViews();
    }

    /**
     * setBox: 设置左右边距
     */
    public void setHPadding(int hPadding) {
        childHPadding = hPadding;
        initViews();
    }

    /**
     * setBox: 设置上下边距
     */
    public void setVPadding(int VPadding) {
        childVPadding = VPadding;
        initViews();
    }

    /**
     * setBox: 设置文本类型
     */
    public void setInputType(String type) {
        inputType = type;
        initViews();
    }

    /**
     * setBox: 设置宽度
     */
    public void setBoxWidth(int width) {
        boxWidth = width;
        initViews();
    }

    /**
     * setBox: 设置高度
     */
    public void setBoxHeight(int height) {
        boxHeight = height;
        initViews();
    }

    /**
     * setBox: 设置焦点样式
     */
    public void setBoxBgFocus(Element bgFocus) {
        boxBgFocus = bgFocus;
        initViews();
    }

    /**
     * setBox: 设置默认样式
     */
    public void setBoxBgNormal(Element bgNormal) {
        boxBgNormal = bgNormal;
        initViews();
    }

    @Override
    public void onTextUpdated(String charSequence, int start, int i1, int count) {
        LogUtil.info(TAG, "charSequence: " + charSequence);
        if (charSequence.length() == 1) {
            focus();
            checkAndCommit();
        } else if (charSequence.length() > 1 && currentText != null){
            currentText.setText(currentText.getText().substring(1));
        }
    }

    private void initViews() {

        KeyEventListener onKeyListener = new KeyEventListener() {
            @Override
            public boolean onKeyEvent(Component component, KeyEvent keyEvent) {
                if (keyEvent.isKeyDown()) {
                    int keyCode = keyEvent.getKeyCode();
                    if (keyCode == KeyEvent.KEY_DEL) {
                        backFocus();
                    }
                }
                return true;
            }
        };

        for (int i = 0; i < box; i++) {
            DirectionalLayout.LayoutConfig layoutParams = new DirectionalLayout.LayoutConfig(boxWidth, boxHeight);
            TextField editText = new TextField(getContext());
            layoutParams.setMarginBottom(childVPadding);
            layoutParams.setMarginTop(childVPadding);
            layoutParams.setMarginLeft(childHPadding);
            layoutParams.setMarginRight(childHPadding);
            layoutParams.alignment = LayoutAlignment.CENTER;

            setBg(editText, false);
            editText.setTextColor(Color.BLACK);
            editText.setLayoutConfig(layoutParams);
            editText.setTextAlignment(CENTER);
            editText.setMaxTextLines(1);
            editText.setSelectionColor(Color.TRANSPARENT);

            if (TYPE_NUMBER.equals(inputType)) {
                editText.setTextInputType(PATTERN_NUMBER);
            } else if (TYPE_PASSWORD.equals(inputType)){
                editText.setTextInputType(PATTERN_PASSWORD);
            } else if (TYPE_TEXT.equals(inputType)){
                editText.setTextInputType(PATTERN_TEXT);
            } else if (TYPE_PHONE.equals(inputType)){
                editText.setTextInputType(PATTERN_NUMBER);
//                editText.setInputType(InputType.TYPE_CLASS_PHONE);
            }
            editText.setId(i);
            editText.setKeyEventListener(onKeyListener);
            editText.addTextObserver(this);
            editText.setFocusChangedListener(this);
            addComponent(editText,i);
        }
    }

    private void backFocus() {
        int count = getChildCount();
        TextField editText;
        for (int i = count-1; i>= 0; i--) {
            editText = (TextField) getComponentAt(i);
            if (editText.getText().length() == 1) {
                if (!editText.isFocused()) {
                    currentText.setText("");
                    editText.requestFocus();
                    return;
                } else {
                    editText.setText("");
                }
            }
        }
    }

    private void focus() {
        int count = getChildCount();
        TextField editText ;
        for (int i = 0; i< count; i++) {
            editText = (TextField) getComponentAt(i);
            if (editText.getText().length() < 1) {
                editText.requestFocus();
                return;
            }
        }
    }

    private void setBg(TextField editText, boolean focus) {
        if (boxBgNormal != null && !focus) {
            editText.setBackground(boxBgNormal);
        } else if (boxBgFocus != null && focus) {
            editText.setBackground(boxBgFocus);
        }
    }

    private void checkAndCommit() {
        StringBuilder stringBuilder = new StringBuilder();
        boolean full = true;
        for (int i = 0 ;i < box; i++){
            TextField editText = (TextField) getComponentAt(i);
            String content = editText.getText();
            if ( content.length() == 0) {
                full = false;
                break;
            } else {
                stringBuilder.append(content);
            }

        }
        LogUtil.debug(TAG, "checkAndCommit:" + stringBuilder.toString());
        if (full){

            if (listener != null) {
                listener.onComplete(stringBuilder.toString());
                setEnabled(false);
            }

        }
    }

    @Override
    public void setEnabled(boolean enabled) {
        int childCount = getChildCount();

        for (int i = 0; i < childCount; i++) {
            Component child = getComponentAt(i);
            child.setEnabled(enabled);
        }
    }

    public void setOnCompleteListener(Listener listener){
        this.listener = listener;
    }

    @Override
    public boolean onEstimateSize(int widthMeasureSpec, int heightMeasureSpec) {
        int parentWidth = getEstimatedWidth();
        LogUtil.info(TAG, "onMeasure width " + parentWidth);

        int count = getChildCount();
        for (int i = 0; i < count; i++) {
            Component child = getComponentAt(i);
            measureChild(child, widthMeasureSpec, heightMeasureSpec);
        }
        if (count > 0) {
            Component child = getComponentAt(0);
            int cWidth = child.getEstimatedWidth();
            int cHeight = child.getEstimatedHeight();

            int maxH = cHeight + 2 * childVPadding;
            int maxW = (cWidth) * count + childHPadding * (count + 1);
            setEstimatedSize(EstimateSpec.getChildSizeWithMode(maxW, widthMeasureSpec, EstimateSpec.NOT_EXCEED),
                EstimateSpec.getChildSizeWithMode(maxH, heightMeasureSpec, EstimateSpec.NOT_EXCEED));
        }
        return true;
    }

    private void measureChild(Component child, int parentWidthMeasureSpec, int parentHeightMeasureSpec) {
        LayoutConfig lc = child.getLayoutConfig();
        int childWidthMeasureSpec =
            EstimateSpec.getChildSizeWithMode(lc.width, parentWidthMeasureSpec, EstimateSpec.NOT_EXCEED);
        int childHeightMeasureSpec =
            EstimateSpec.getChildSizeWithMode(lc.height, parentHeightMeasureSpec, EstimateSpec.NOT_EXCEED);
        child.estimateSize(childWidthMeasureSpec, childHeightMeasureSpec);
    }

    @Override
    public boolean onArrange(int l, int t, int r, int b) {
        int childCount = getChildCount();

        for (int i = 0; i < childCount; i++) {
            Component child = getComponentAt(i);

            child.setVisibility(VISIBLE);
            int cWidth = child.getEstimatedWidth();
            int cHeight = child.getEstimatedHeight();
            int cl = childHPadding + (i) * (cWidth + childHPadding);
            int ct = childVPadding;
            child.arrange(cl, ct, cWidth, cHeight);
        }
        return true;
    }

    @Override
    public void onFocusChange(Component component, boolean b) {
        if (b) {
            currentText = (TextField) component;
        }
    }

    public interface Listener {
       void onComplete(String content);
    }
}

